home *** CD-ROM | disk | FTP | other *** search
/ Aminet 24 / Aminet 24 (1998)(GTI - Schatztruhe)[!][Apr 1998].iso / Aminet / dev / c / AmiVoGL_MDEV.lha / src / curves.c < prev    next >
C/C++ Source or Header  |  1994-04-12  |  5KB  |  290 lines

  1. #include "vogl.h"
  2.  
  3. static    int    nsegs = 15;
  4. static    Matrix    e;
  5.  
  6. void     drcurve();
  7.  
  8. /*
  9.  * curvebasis
  10.  *
  11.  *      sets the basis type of curves.
  12.  *
  13.  */
  14. void curvebasis(short id)
  15. {
  16. if(!vdevice.initialised)
  17. verror("curvebasis: vogl not initialised");
  18.  
  19. copymatrix(vdevice.tbasis, vdevice.bases[id]);
  20. }
  21.  
  22. /* ------------------------------------------------------------------------ */
  23.  
  24.        
  25. /*
  26.  * curveprecision
  27.  *
  28.  *    sets the number of line segments that make up a curve segment.
  29.  *
  30.  */
  31. void curveprecision(short nsegments)
  32. {
  33. float    n2, n3;
  34.  
  35. if (nsegments > 0)
  36. nsegs = nsegments;
  37. else
  38. verror("curveprecision: number of segments <= 0");
  39.  
  40. /*
  41.  * Set up the difference matrix.
  42.  */
  43. identmatrix(e);
  44. n2 = (float)(nsegs * nsegs);
  45. n3 = (float)(nsegs * n2);
  46.  
  47. e[0][0] = e[2][2] = e[3][3] = 0.0;
  48. e[1][0] = 1.0 / n3;
  49. e[1][1] = 1.0 / n2;
  50. e[2][0] = e[3][0] = 6.0 / n3;
  51. e[2][1] = 2.0 / n2;
  52. e[1][2] = 1.0 / (float)nsegs;
  53. e[0][3] = 1.0;
  54. }
  55.  
  56. /* ------------------------------------------------------------------------ */
  57.  
  58. /*
  59.  * rcrv
  60.  *
  61.  *    draws a rational curve
  62.  *
  63.  */
  64. void rcrv(Coord geom[4][4])
  65. {
  66. Matrix    d, tmp;
  67. float    *m, xlast, ylast, zlast;
  68. Token    *tok;
  69. int    i;
  70.  
  71. if (!vdevice.initialised)
  72. verror("rcrv: vogl not initialised");
  73.  
  74.  
  75. mult4x4(d, vdevice.tbasis, geom);
  76.  
  77. /*
  78.  * Find the last point on the curve....
  79.  */
  80. xlast = d[0][0] + d[1][0] + d[2][0] + d[3][0];
  81. ylast = d[0][1] + d[1][1] + d[2][1] + d[3][1];
  82. zlast = d[0][2] + d[1][2] + d[2][2] + d[3][2];
  83.  
  84. /*
  85.  * Mult. by the precision matrix....
  86.  */
  87. mult4x4(tmp, e, d);
  88.  
  89. if (vdevice.inobject) {
  90.     tok = newtokens(21);
  91.  
  92.     tok[0].i = RCURVE;
  93.     (++tok)->i = nsegs;
  94.     (++tok)->f = xlast;
  95.     (++tok)->f = ylast;
  96.     (++tok)->f = zlast;
  97.     m = (float *)tmp;
  98.     for (i = 0; i < 16; i++)
  99.     (++tok)->f = *m++;
  100.  
  101.     return;
  102.     }
  103.  
  104. /*
  105.  * Multiply by the current transformation matrix.
  106.  */
  107. mult4x4(d, tmp, vdevice.transmat->m);
  108.  
  109. /*
  110.  * Draw the curve.....
  111.  */
  112. drcurve(nsegs, d);
  113. /*
  114.  * Set the current world position to the last point (This
  115.  * is the untransformed one)
  116.  */
  117. vdevice.cpW[V_X] = xlast;
  118. vdevice.cpW[V_Y] = ylast;
  119. vdevice.cpW[V_Z] = zlast;
  120. }
  121.  
  122. /* ------------------------------------------------------------------------ */
  123.  
  124. /*
  125.  * crv
  126.  *
  127.  *    draws a curve
  128.  *
  129.  */
  130. void crv(Coord geom[4][3])
  131. {
  132. Matrix    tmp;
  133. int    i, j;
  134.  
  135. if (!vdevice.initialised)
  136. verror("crv: vogl not initialised");
  137.  
  138. /*
  139.  * Fill in the w column for rcurve
  140.  */
  141. for (i = 0; i < 4; i++) {
  142.     tmp[i][3] = 1.0;
  143.     for (j = 0; j < 3; j++) 
  144.     tmp[i][j] = geom[i][j];
  145.     }
  146.  
  147. rcrv(tmp);
  148. }
  149.  
  150. /* ------------------------------------------------------------------------ */
  151.  
  152. /*
  153.  *  drcurve
  154.  *
  155.  *    Iterate a forward difference matrix to draw a curve.
  156.  *    Also bypasses the normal multiplication by the current
  157.  *      transformation matrix (ie. goes straight to clip).
  158.  */
  159. void drcurve(
  160.   int n,
  161.   Matrix r)
  162. {
  163. int    it, vx, vy;
  164.  
  165. vdevice.cpVvalid = 0;        /* we start loop with a "move" */
  166. if (vdevice.clipoff) {
  167.     vdevice.cpVx = WtoVx(r[0]);        
  168.     vdevice.cpVy = WtoVy(r[0]);        
  169.     }
  170.  
  171. for (it = 0; it < n; it++) {
  172.     vdevice.cpWtrans[V_X] = r[0][V_X];
  173.     vdevice.cpWtrans[V_Y] = r[0][V_Y];
  174.     vdevice.cpWtrans[V_Z] = r[0][V_Z];
  175.     vdevice.cpWtrans[V_W] = r[0][V_W];
  176.  
  177.     /* These loops now unwound ....
  178.      * for (i = 0; i < 4; i++)
  179.      *    for (j = 0; j < 3; j++)
  180.      *        r[j][i] += r[j+1][i];
  181.      */
  182.  
  183.     r[0][0] += r[1][0];
  184.     r[1][0] += r[2][0];
  185.     r[2][0] += r[3][0];
  186.  
  187.     r[0][1] += r[1][1];
  188.     r[1][1] += r[2][1];
  189.     r[2][1] += r[3][1];
  190.  
  191.     r[0][2] += r[1][2];
  192.     r[1][2] += r[2][2];
  193.     r[2][2] += r[3][2];
  194.  
  195.     r[0][3] += r[1][3];
  196.     r[1][3] += r[2][3];
  197.     r[2][3] += r[3][3];
  198.  
  199.     if (vdevice.clipoff) {
  200.         vx = WtoVx(r[0]);        /* just draw it */
  201.         vy = WtoVy(r[0]);
  202.          
  203.         (*vdevice.dev.Vdraw)(vx, vy);
  204.  
  205.         vdevice.cpVx = vx;
  206.         vdevice.cpVy = vy;
  207.  
  208.         vdevice.cpVvalid = 0;
  209.         }
  210.     else {
  211.         if (vdevice.cpVvalid)
  212.         quickclip(vdevice.cpWtrans, r[0]);
  213.         else
  214.         clip(vdevice.cpWtrans, r[0]);
  215.         }
  216.     }
  217.  
  218. vdevice.cpWtrans[V_X] = r[0][V_X];
  219. vdevice.cpWtrans[V_Y] = r[0][V_Y];
  220. vdevice.cpWtrans[V_Z] = r[0][V_Z];
  221. vdevice.cpWtrans[V_W] = r[0][V_W];
  222.  
  223. /*
  224.  * must set current world position here - clip or quickclip will have
  225.  * set valid to the approriate value.
  226.  */
  227. }
  228.  
  229. /* ------------------------------------------------------------------------ */
  230.  
  231. /*
  232.  * crvn
  233.  *
  234.  *    draws a series of curve segments.
  235.  *
  236.  */
  237. void crvn(
  238.   long n,
  239.   Coord geom[][3])
  240. {
  241. int    i;
  242.  
  243. if (!vdevice.initialised)
  244. verror("crvn: vogl not initialised");
  245.  
  246. if (n < 4)
  247. verror("crvn: not enough points in geometry matrix");
  248.  
  249. for (i = 0; i <= n - 4; i++) crv((Coord (*)[3]) &geom[i][0]);
  250. }
  251.  
  252. /* ------------------------------------------------------------------------ */
  253.  
  254. /*
  255.  * rcrvn
  256.  *
  257.  *    draws a series of rational curve segments.
  258.  *
  259.  */
  260. void rcrvn(
  261.   long n,
  262.   Coord geom[][4])
  263. {
  264. int    i;
  265.  
  266. if (!vdevice.initialised)
  267. verror("rcrvn: vogl not initialised");
  268.  
  269. if (n < 4)
  270. verror("rcrvn: not enough points in geometry matrix");
  271.  
  272. for (i = 0; i <= n - 4; i++) rcrv((Coord (*)[4]) &geom[i][0]);
  273. }
  274.  
  275. /* ------------------------------------------------------------------------ */
  276.  
  277. /*
  278.  * curveit
  279.  *
  280.  *    Iterates the top matrix on the stack as a forward difference
  281.  *    matrix, drawing as it goes along.
  282.  */
  283. void curveit(short n)
  284. {
  285. drcurve((int)n, vdevice.transmat->m);
  286. }
  287.  
  288. /* ------------------------------------------------------------------------ */
  289.  
  290.